#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>
#include<string>

void Usage(std::string proc)
{
    std::cerr<<"Usage: "<<proc<<"serverip serverport"<<std::endl;
}
int main(int argc,char*argv[])
{
    
     if(argc!=3)
    {
        Usage(argv[0]);
        exit(0);
    }

    std::string serverip=argv[1];
    uint16_t serverport=std::stoi(argv[2]);

    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
        {
            std::cout<<"creat socket error"<<std::endl;
            return 0;
        }
        //[srcip,srcport],[dstip,dsport];
        //客户端要不要显示bind自己的IP和端口？不要！！！
        //client要不要 隐式bind ip和端口？ 要！！！
        //why? client会在自己os的帮助下，随机bind端口号 //服务端一定是具体的，可以明确规定的；
        struct sockaddr_in server;
        memset(&server,0,sizeof(server));//将指针 s所指向的内存区域的 前 n个字节，全部设置为值 c（该值会被转换为 unsigned char，即一个字节）
        server.sin_family=AF_INET;
        server.sin_port=htons(serverport);
        server.sin_addr.s_addr=inet_addr(serverip.c_str());

        while(true)
        {
            std::cout << "Please Enter@ ";
            std::string line;
            std::getline(std::cin,line);

            //写
            sendto(sockfd,line.c_str(),line.size(),0,(struct sockaddr*)&server,sizeof(server));  /*服务器ip和端口号*/
            //软件会以各种形式，将目标服务器ip和端口号内置在客户端里。客户端和服务端是一家公司程序员写的

            //读
            struct sockaddr_in temp;
            socklen_t len=sizeof(temp);
            char buffer[1024];
            int m=recvfrom(sockfd,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&len);
            if(m>0)
            {
                buffer[m]=0;
                std::cout<<buffer<<std::endl;
            }

        }
    

    return 0;
}

